package com.czh.config;

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;

import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 声明一个线程池
 * 为什么需要定义多个线程池: 资源隔离(不同任务使用不同的线程池)、任务类型和优先级(并发高的使用较大的线程池，I/O高的使用小一点的)
 *
 * @author chenzhihua
 * @Date 2024/8/7
 */
@EnableAsync
@Configuration
public class AsyncConfiguration implements AsyncConfigurer {
    // 声明一个线程池
    @Bean("taskExecutor")
    public Executor taskExecutor() {
        return new ThreadPoolExecutor(8, 20, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>(500));
    }

    // 声明另一个线程池
    @Bean("backgroundTaskExecutor")
    public Executor backgroundTaskExecutor() {
        return new ThreadPoolExecutor(
                4, // 核心线程池大小
                10, // 最大线程池大小
                5, // 线程闲置超时回收时间
                TimeUnit.MINUTES,
                new LinkedBlockingQueue<>(200) // 阻塞队列
        );
    }

    /**
     * 非必实现: 处理异步方法中的异常
     *
     * @return
     */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new SimpleAsyncUncaughtExceptionHandler();
    }
}
